package com.fc.advbox.controller.api;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fc.advbox.common.ResponseJson;
import com.fc.advbox.controller.admin.BaseController;
import com.fc.advbox.dto.contract.ContractTotalInfo;
import com.fc.advbox.dto.org.ContractRequest;
import com.fc.advbox.entity.ContractEntity;
import com.fc.advbox.entity.EquipmentEntity;
import com.fc.advbox.service.IContractService;
import com.fc.advbox.service.IEquipmentService;
import com.fc.advbox.utils.Constant;
import com.fc.advbox.utils.PageUtils;
import com.fc.advbox.utils.Query;
import com.fc.advbox.utils.RRException;
import com.fc.advbox.utils.validator.ValidatorUtils;
import com.fc.advbox.utils.validator.group.AddGroup;
import com.fc.advbox.utils.validator.group.UpdateGroup;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.map.HashedMap;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * ContractController
 *
 * @author Gary.Jiang
 * @date 2018/6/22.15:37
 */
@RestController
@RequestMapping("/api/contract/org")
@Api(value="合同接口", tags={"合同接口"})
@Slf4j
public class ContractController extends BaseController {
    @Autowired
    private IContractService contractService;

    @Autowired
    private IEquipmentService equipmentService;
    /**
     * 所有机构合同列表, 包括: 代理商合同, 渠道商合同, 广告位租赁合同
     */
    @PostMapping("/list")
    @ApiOperation(value = "查询机构合同列表", httpMethod="POST",
            notes = " REST 方式请求," +
                    "Request Params: <ul>" +
                    "<li><i>查询合同到期提醒列表请添加参数: interva, 如查询30天到期, interva=30" +
                    "<li><i>可选参数: name: string </i></li>" +
                    "<li><i>可选参数: type: string AGENT:代理合同，CHANNEL:渠道合同，RENT：广告商租赁合同</i></li>" +
                    "<li><i>可选参数: area: string </i></li>" +
                    "<li><i>可选参数: city: string </i></li>" +
                    "<li><i>可选参数: status: String (drafting -- 草稿,保存   confirmed -- 合同已确定   termination -- 终止) </i></li>" +
                    "<li><i>可选参数: startDate: 开始时间  格式：yyyy-MM-dd HH:mm:SS 例如 2018-06-19 07:54:01</i></li>" +
                    "<li><i>可选参数: endDate: 结束时间  格式：yyyy-MM-dd HH:mm:SS 例如 2018-06-19 07:54:01</i></li>" +
                    "<li><i>默认参数: page: 1, 当前页，默认值1 </i></li>" +
                    "<li><i>默认参数: limit: 20 </i></li>" +
                    "</ul>")
    @RequiresPermissions("api:org:contract:view")
    public ResponseJson<PageUtils<ContractEntity>> query(@RequestBody(required = false) ContractRequest request){
        if(request == null){
            request = new ContractRequest();
        }

        Map<String, Object> params = request.toMap();
        log.info("query contracts, params:{}", request);
        //校对并赋值 offset和limit
        calculatePagination(params);

        Query query = new Query(params);
        List<ContractEntity> list = contractService.queryList(query);
        int total = contractService.queryTotal(query);

        PageUtils pageUtil = new PageUtils(list, total, query.getLimit(), query.getPage());

        return ResponseJson.success(pageUtil);
    }

    /**
     * 获取乙方组织的所有合同
     */
    @GetMapping("/{orgId}")
    @ApiOperation(value = "获取制定乙方机构下的合同列表", httpMethod="GET")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "orgId", required = true, dataType = "long", value="机构ID"),
    })
    @RequiresPermissions("api:org:contract:view")
    public ResponseJson<ContractEntity> getOrgContractList(@PathVariable Long orgId){
        Map<String , Object> params = new HashedMap();
        params.put("yiOrgId",orgId);
        List<ContractEntity> contractList = contractService.queryList(params);
        return ResponseJson.success(contractList);
    }

    /**
     * 获取乙方组织的合同总信息
     */
    @PostMapping("/totalInfo")
    @ApiOperation(value = "获取乙方名下的合同总信息", httpMethod="POST",
            notes = " REST 方式请求," +
                    "Request Params: <ul>" +
                    "<li><i>必填参数: orgId: 乙方组织ID </i></li>" +
                    "<li><i>选填参数: type: string AGENT:代理合同，CHANNEL:渠道合同，RENT：广告商租赁合同</i></li>" +
                    "</ul>")
    @RequiresPermissions("api:org:contract:view")
    public ResponseJson getOrgContractTotalInfo(@RequestBody JSONObject params){
        if(params.get("orgId") == null)
        {
            throw new RRException("orgId不能为空!");
        }

        if(params.get("type") != null && !Constant.ContractType.verify(params.getString("type")))
        {
            throw new RRException("合同类型(type)的值不正确!");
        }
        params.put("currentDate", new Date());

        ContractTotalInfo contractTotalInfo = contractService.getContractTotalInfoByOrgId(params);
        if(contractTotalInfo == null)
        {
            contractTotalInfo = new ContractTotalInfo();
        }
        return ResponseJson.success(contractTotalInfo);
    }

    /**
     * 获取单个合同
     */
    @GetMapping("/contract/{id}")
    @ApiOperation(value = "获取单个机构合同", httpMethod="GET")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "id", required = true, dataType = "long", value="合同ID"),
    })
    @RequiresPermissions("api:org:contract:view")
    public ResponseJson<ContractEntity> get(@PathVariable Long id){
        ContractEntity contractEntity = contractService.queryObject(id);
        return ResponseJson.success(contractEntity);
    }

    /**
     * 保存合同
     */
    @PostMapping("/save")
    @ApiOperation(value = "添加机构合同", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>jiaOrgId: 甲方机构Id </i></li>" +
                    "<li><i>yiOrgId: 乙方机构Id </i></li>" +
                    "<li><i>name: 合同名称 </i></li>" +
                    "<li><i>province: 省份 </i></li>" +
                    "<li><i>city: 城市 </i></li>" +
                    "<li><i>area: 地区 </i></li>" +
                    "<li><i>contactor: 联系人 </i></li>" +
                    "<li><i>contactPhone: 联系人电话 </i></li>" +
                    "<li><i>descn: 描述 </i></li>" +
                    "<li><i>type: 类型 </i></li>" +
                    "<li><i>amount: 金额 </i></li>" +
                    "<li><i>equipmentNum: 设备数量 </i></li>" +
                    "<li><i>equipmentIds: 合同涉及的设备ID, List, 例如 {1,2,3} </i></li>" +
                    "<li><i>agentAmount: 代理费 </i></li>" +
                    "<li><i>returnAmount: 单台机器落地安装返利 </i></li>" +
                    "<li><i>benifitRate: 利润占比 </i></li>" +
                    "<li><i>startDate: 开始时间  格式：yyyy-MM-dd HH:mm:SS 例如 2018-06-19 07:54:01</i></li>" +
                    "<li><i>endDate: 结束时间  格式：yyyy-MM-dd HH:mm:SS 例如 2018-06-19 07:54:01</i></li>" +
                    "</ul>")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", name = "entity", required = true, dataType = "ContractEntity", value="合同对象"),
    })
    @RequiresPermissions("api:org:contract:edit")
    public ResponseJson save(@RequestBody ContractEntity entity){
        log.info("save a contract: {}", entity);
        ValidatorUtils.validateEntity(entity, AddGroup.class);
        if(!Constant.ContractType.verify(entity.getType())){
            return ResponseJson.error("非法合同类型!");
        }
        if(entity.getEndDate().getTime() <= entity.getStartDate().getTime()){
            return ResponseJson.error("合同截至时间应该晚于起始时间!");
        }
        if(entity.getEquipmentIds() == null || entity.getEquipmentIds().isEmpty()){
            throw new RRException("请选择至少一台设备!");
        }

        contractService.save(entity);

        return ResponseJson.success();
    }

    /**
     * 更新合同
     */
    @PutMapping("/update")
    @ApiOperation(value = "更新机构合同", response = ResponseJson.class, httpMethod="PUT",
            notes = " REST 方式请求" +
                    "Request Body: <ul>" +
                    "<li><i>jiaOrgId: 甲方机构Id </i></li>" +
                    "<li><i>yiOrgId: 乙方机构Id </i></li>" +
                    "<li><i>name: 合同名称 </i></li>" +
                    "<li><i>province: 省份 </i></li>" +
                    "<li><i>city: 城市 </i></li>" +
                    "<li><i>area: 地区 </i></li>" +
                    "<li><i>contactor: 联系人 </i></li>" +
                    "<li><i>contactPhone: 联系人电话 </i></li>" +
                    "<li><i>descn: 描述 </i></li>" +
                    "<li><i>type: 类型 </i></li>" +
                    "<li><i>amount: 金额 </i></li>" +
                    "<li><i>equipmentNum: 设备数量 </i></li>" +
                    "<li><i>agentAmount: 代理费 </i></li>" +
                    "<li><i>returnAmount: 单台机器落地安装返利 </i></li>" +
                    "<li><i>benifitRate: 利润占比 </i></li>" +
                    "<li><i>startDate: 开始时间  格式：yyyy-MM-dd HH:mm:SS 例如 2018-06-19 07:54:01</i></li>" +
                    "<li><i>endDate: 结束时间  格式：yyyy-MM-dd HH:mm:SS 例如 2018-06-19 07:54:01</i></li>" +
                    "</ul>")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "body", name = "entity", required = true, dataType = "ContractEntity", value="合同对象"),
    })
    @RequiresPermissions("api:org:contract:edit")
    public ResponseJson update(@RequestBody ContractEntity entity){
        log.info("update a contract: {}", entity);
        ValidatorUtils.validateEntity(entity, UpdateGroup.class);
        if(!Constant.ContractType.verify(entity.getType())){
            return ResponseJson.error("非法合同类型!");
        }
        if(entity.getEndDate().getTime() <= entity.getStartDate().getTime()){
            return ResponseJson.error("合同截至时间应该晚于起始时间!");
        }
        if(entity.getEquipmentIds() == null || entity.getEquipmentIds().isEmpty()){
            throw new RRException("请选择至少一台设备!");
        }

        contractService.update(entity);

        return ResponseJson.success();
    }

    /**
     * 删除合同
     */
    @DeleteMapping("/{id}")
    @ApiOperation(value = "删除机构合同", response = ResponseJson.class, httpMethod="DELETE")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "id", required = true, dataType = "long", value="合同ID"),
    })
    @RequiresPermissions("api:org:contract:eidt")
    public ResponseJson delete(@PathVariable Long id){
        contractService.delete(id);
        return ResponseJson.success();
    }

    /**
     * 确定合同
     */
    @PostMapping("/confirm")
    @ApiOperation(value = "确认合同", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
            "Request Body: " +
            "<ul>" +
            "<li><i>id: 合同ID </i></li>" +
            "</ul>")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "requestBody", name = "id", required = true, dataType = "long", value="合同ID"),
    })
    @RequiresPermissions("api:org:contract:audit")
    public ResponseJson confirmContract(@RequestBody JSONObject params){
        log.info("confirm contract: {}", JSON.toJSONString(params));
        Long contractId = params.getLong("id");
        if(contractId == null){
            throw new RRException("合同ID不能为空!");
        }
        contractService.confirmContract(contractId);
        return ResponseJson.success();
    }

    /**
     * 终止合同
     */
    @PostMapping("/terminate")
    @ApiOperation(value = "终止合同", response = ResponseJson.class, httpMethod="POST",
            notes = " REST 方式请求" +
                    "Request Body: " +
                    "<ul>" +
                    "<li><i>id: 合同ID </i></li>" +
                    "</ul>")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "requestBody", name = "id", required = true, dataType = "long", value="合同ID"),
    })
    @RequiresPermissions("api:org:contract:audit")
    public ResponseJson terminateContract(@RequestBody JSONObject params){
        log.info("terminate contract: {}", JSON.toJSONString(params));
        Long contractId = params.getLong("id");
//        Date endDate = params.getDate("endDate");
        Date endDate = new Date(); // todo need from client，and a task job run to execute contract, equipment and holding status
        if(contractId == null){
            throw new RRException("合同ID不能为空!");
        }
//        if(endDate == null)
//        {
//            throw new RRException("终止时间不能为空!");
//        }
        contractService.terminateContract(contractId, endDate);
        return ResponseJson.success();
    }

    /**
     * 通过合同ID获取设备列表
     */
    @PostMapping("/{contractId}/equipments")
    @ApiOperation(value = "通过合同ID获取设备列表", httpMethod="POST",
            notes=" POST " +
                    "Request Body: <ul>" +
                    "<li><i>默认参数: page: 1, 当前页，默认值1</i></li>" +
                    "<li><i>默认参数: limit: 每次查询个数，默认为20</i></li>" +
                    "</ul>")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "path", name = "contractId", required = true, dataType = "long", value="合同ID"),
    })
    @RequiresPermissions("api:equipment:view")
    public ResponseJson queryEquipmentList(@PathVariable Long contractId, @RequestBody JSONObject params){
        params.put("contractId", contractId);
        //校对并赋值 offset和limit
        calculatePagination(params);

        List<EquipmentEntity> equipmentEntityList = equipmentService.queryEquipmentsByContractId(params);
        return ResponseJson.success(equipmentEntityList);
    }

}
